<template>
  <div class="page-box">

    <el-form class="search" label-width="70px">
      <el-form-item label="品类类型">
        <el-select v-model="listModel.specCategoryType" placeholder="选择品类类型" clearable>
          <el-option v-for="item in specCategoryTypes" :key="item.id" :label="item.typeName" :value="item.id" />
        </el-select>
      </el-form-item>
      <el-form-item label="规格品类">
        <el-select v-model="listModel.specCategoryId" placeholder="选择品类" clearable>
          <el-option v-for="item in specCategories" :key="item.id" :label="item.specCategoryName" :value="item.id" />
        </el-select>
      </el-form-item>
      <el-form-item label="规格名称">
        <el-input v-model="listModel.specName" placeholder="规格名称" clearable />
      </el-form-item>
      <el-form-item class="search-btn">
        <el-button type="primary" icon="Search" @click="pageSizeChange">搜索</el-button>
        <el-button icon="RefreshRight" @click="resetList">重置</el-button>
      </el-form-item>
    </el-form>

    <div class="head">
      <span class="title">商品规格管理</span>
      <div class="toolbar">
        <el-button type="primary" icon="Plus" @click="addOrModify(null)">添加</el-button>
        <el-button type="primary" icon="Refresh" @click="fetchListData">刷新</el-button>
        <el-button type="danger" icon="Delete" @click="isShowDelDialog = true">批量删除</el-button>
      </div>
    </div>

    <div class="table">
      <el-table
          stripe
          v-loading="loading"
          :data="listData"
          row-key="id"
          @selection-change="selectionChange"
      >
        <el-table-column type="selection" width="30" />
        <el-table-column prop="specCategoryName" label="品类" />
        <el-table-column prop="specName" label="规格" align="right" />
        <el-table-column label="规格项" #default="{ row }" width="360">
          <div class="spec-item-box">
            <div v-for="specItem in row.specItems" :key="specItem.id" class="spec-item">
              <el-tag :disable-transitions="true" round>{{ specItem.specValue }}</el-tag>
            </div>
          </div>
        </el-table-column>
        <el-table-column prop="specSort" label="排序" align="right" width="70" />
        <el-table-column prop="created" label="创建时间" align="right" width="138" />
        <el-table-column label="操作" fixed="right" width="130" align="center" #default="{ row }">
          <el-button type="primary" icon="Edit" @click="addOrModify(row)" />
          <el-button type="danger" icon="Delete" @click="del(row.id)" />
        </el-table-column>
      </el-table>
    </div>
    <el-pagination
        class="pagination"
        v-model:current-page="listModel.current"
        v-model:page-size="listModel.size"
        :page-sizes="[10, 30, 50]"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="pageSizeChange"
        @current-change="fetchListData"
    />

    <el-drawer
        size="50%"
        :title="addOrModifyDrawerTitle"
        v-model="isShowAddOrModifyDrawer"
        direction="rtl"
        :before-close="addOrModifyDrawerClose"
        @opened="addOrModifyDrawerOpened(addOrModifyFormRef)"
    >
      <div class="form-content">
        <el-form ref="addOrModifyFormRef" label-width="70px" :model="addOrModifyModel" :rules="addOrModifyRules">
          <el-form-item label="类型" prop="specCategoryId">
            <el-select v-model="specCategoryType" placeholder="选择品类类型" @change="fetchSpecCategoriesByType" clearable>
              <el-option v-for="item in specCategoryTypes" :key="item.id" :label="item.typeName" :value="item.id" />
            </el-select>
          </el-form-item>
          <el-form-item label="品类" prop="specCategoryId">
            <el-select v-model="addOrModifyModel.specCategoryId" placeholder="选择品类" clearable>
              <el-option v-for="item in addOrModifyCategories" :key="item.id" :label="item.specCategoryName" :value="item.id" />
            </el-select>
          </el-form-item>
          <el-form-item label="名称" prop="specName">
            <el-input v-model="addOrModifyModel.specName" placeholder="规格名称" autocomplete="off" clearable />
          </el-form-item>
          <el-form-item label="排序" prop="specSort">
            <el-input v-model="addOrModifyModel.specSort" placeholder="规格排序" autocomplete="off" clearable />
          </el-form-item>
          <el-form-item prop="specItems">
            <el-button type="success" @click="addSpecItem">添加规格</el-button>
          </el-form-item>
          <el-form-item>
            <div v-for="(specItem, index) in addOrModifyModel.specItems" :key="index" style="margin-right: 10px;">
              <el-tag
                  @click.stop="toggleSpecItem(index)"
                  v-show="!specItem.isInput"
                  closable
                  :disable-transitions="true"
                  @close="removeSpecItem(index)"
              >
                {{ specItem.specValue }}
              </el-tag>
              <el-input
                  ref="specItemInputRef"
                  v-show="specItem.isInput"
                  v-model="specItem.specValue"
                  style="width: 86px;"
                  size="small"
                  @keyup.enter="$event.target.blur()"
                  @blur="handleSpecItemInput(index, specItem.specValue)"
              />
            </div>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" :loading="loading" @click="doAddOrModify">
              {{ loading ? '正在提交 ...' : '提交' }}
            </el-button>
            <el-button @click="addOrModifyDrawerClose">取消</el-button>
          </el-form-item>
        </el-form>
      </div>
    </el-drawer>

    <el-dialog
        v-model="isShowDelDialog"
        title="提示"
        width="30%"
        :before-close="delDialogClose"
    >
      <span>确定要删除吗？</span>
      <template #footer>
        <span>
          <el-button @click="delDialogClose">取消</el-button>
          <el-button type="primary" :loading="loading" @click="doDel">
            {{ loading ? '正在删除 ...' : '确定' }}
          </el-button>
        </span>
      </template>
    </el-dialog>

  </div>
</template>

<script setup>
import { ref, onMounted, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { GetListData, AddData, ModifyData, DeleteData } from '@/api/goods/spec'
import { categoryTypes, GetAllData as GetSpecCategories, GetDataByType } from '@/api/goods/specCategory'

const loading = ref(false)
const specCategoryTypes = ref(categoryTypes)

const specCategories = ref([])

const fetchSpecCategories = async () => {
  const { code, message, data } = await GetSpecCategories()
  if (code !== 200) {
    ElMessage.error(message)
    return
  }
  specCategories.value = data
}

/* 列表开始 */
const total = ref(0)
const listModelData = {
  current: 1,
  size: Number(import.meta.env.VITE_PAGE_SIZE),
  specCategoryType: '',
  specCategoryId: '',
  specName: '',
}
const listModel = ref({ ...listModelData })
const listData = ref([])

const selectionChange = arr => {
  delModel.value.ids = []
  arr.forEach(row => {
    delModel.value.ids.push(row.id)
  })
}

const fetchListData = async () => {
  if (loading.value) {
    return
  }
  loading.value = true
  const { code, message, data } = await GetListData(listModel.value)
  loading.value = false
  if (code !== 200) {
    ElMessage.error(message)
    return
  }
  listData.value = data.records
  total.value = Number(data.total)
}

const pageSizeChange = () => {
  listModel.value.current = 1
  fetchListData()
}

const resetList = () => {
  listModel.value = { ...listModelData }
  fetchListData()
}

onMounted(() => {
  fetchSpecCategories()
  fetchListData()
})
/* 列表结束 */

/* 添加修改开始 */
const specCategoryType = ref('')
const addOrModifyCategories = ref([])
const specItemInputRef = ref()
const originalSpecItems = ref([])
const specItemMap = ref(new Map())
const addOrModifyFormRef = ref()
const addOrModifyDrawerTitle = ref('')
const isShowAddOrModifyDrawer = ref(false)

const addOrModifyData = {
  id: 0,
  specCategoryId: '',
  specName: '',
  specSort: 1,
  specItems: [],
}
const addOrModifyModel = ref({ ...addOrModifyData })

const specItemsValidator = (rule, value, callback) => {
  if (addOrModifyModel.value.specItems.length <= 0) {
    return callback(new Error('请添加规格'))
  }
  addOrModifyModel.value.specItems.forEach(item => {
    if (item.specValue.length <= 0) {
      return callback(new Error('请输入规格'))
    }
  })
  return callback()
}
const addOrModifyRules = ref({
  specCategoryId: [{required: true, message: '请选择规格品类', trigger: 'blur'}],
  specName: [{required: true, message: '请输入规格名称', trigger: 'blur'}],
  specSort: [{required: true, message: '请输入规格排序', trigger: 'blur'}],
  specItems: [
    {required: true, message: '请添加并输入规格', trigger: 'blur'},
    {validator: specItemsValidator, trigger: 'blur'}
  ]
})

const fetchSpecCategoriesByType = async () => {
  const { code, message, data } = await GetDataByType(specCategoryType.value)
  if (code !== 200) {
    ElMessage.error(message)
    return
  }
  addOrModifyCategories.value = data
}

const toggleSpecItem = index => {
  addOrModifyModel.value.specItems[index].isInput = !addOrModifyModel.value.specItems[index].isInput
  nextTick(() => {
    specItemInputRef.value[index].focus()
  })
}

const handleSpecItemInput = (index, val) => {
  if (val.length <= 0) {
    addOrModifyModel.value.specItems.splice(index, 1)
  } else {
    toggleSpecItem(index)
  }
}

const addSpecItem = () => {
  const lastIndex = addOrModifyModel.value.specItems.length
  addOrModifyModel.value.specItems.push({
    id: 0,
    specValue: '',
    isInput: true,
  })
  nextTick(() => {
    specItemInputRef.value[lastIndex].focus()
  })
}

const removeSpecItem = (index) => {
  addOrModifyModel.value.specItems.splice(index, 1)
}

const addOrModify = (row) => {
  if (row == null) {
    addOrModifyDrawerTitle.value = '添加规格'
  } else {
    specCategoryType.value = row.specCategoryType
    addOrModifyDrawerTitle.value = '编辑规格'
    originalSpecItems.value = [ ...row.specItems ]
    addOrModifyModel.value = { ...row }
    addOrModifyModel.value.specItems = [ ...row.specItems ]
    fetchSpecCategoriesByType()
  }
  isShowAddOrModifyDrawer.value = true
}

const doAddOrModify = () => {
  if (loading.value) {
    return
  }

  if (originalSpecItems.value.length > 0) {
    addOrModifyModel.value.specItems.forEach(specItem => {
      specItem.specCategoryId = addOrModifyModel.value.specCategoryId
      specItemMap.value.set(specItem.id, true)
    })
    originalSpecItems.value.forEach(specItem => {
      if (!specItemMap.value.has(specItem.id)) {
        specItem.deleted = 1
        addOrModifyModel.value.specItems.push(specItem)
      }
    })
  }

  addOrModifyFormRef.value.validate(valid => {
    if (!valid) {
      return
    }
    loading.value = true
    let code, message
    setTimeout(async () => {

      if (addOrModifyModel.value.id && addOrModifyModel.value.id > 0) {
        const result = await ModifyData(addOrModifyModel.value)
        code = result.code
        message = result.message
      } else {
        const result = await AddData(addOrModifyModel.value)
        code = result.code
        message = result.message
      }
      loading.value = false
      isShowAddOrModifyDrawer.value = false
      resetAddOrModify()
      if (code !== 200) {
        ElMessage.error(message)
        return
      }
      await fetchListData()
      ElMessage.success(message)

    }, 200)
  })
}

const addOrModifyDrawerOpened = formEl => {
  formEl.clearValidate()
}

const resetAddOrModify = () => {
  specCategoryType.value = ''
  addOrModifyCategories.value = []
  originalSpecItems.value = []
  specItemMap.value = new Map()
  addOrModifyFormRef.value.resetFields()
  addOrModifyModel.value = { ...addOrModifyData }
  loading.value = false
}

const addOrModifyDrawerClose = () => {
  if (loading.value) {
    return
  }
  resetAddOrModify()
  isShowAddOrModifyDrawer.value = false
}
/* 添加修改结束 */

/* 删除开始 */
const isShowDelDialog = ref(false)
const delModel = ref({ ids: [] })

const del = id => {
  delModel.value.ids.push(id)
  isShowDelDialog.value = true
}

const doDel = async () => {
  if (loading.value) {
    return
  }
  if (delModel.value.ids.length <= 0) {
    ElMessage.error('请至少选择一项')
    return
  }
  loading.value = true
  const { code, message } = await DeleteData(delModel.value)
  loading.value = false
  if (code !== 200) {
    ElMessage.error(message)
    return
  }
  isShowDelDialog.value = false
  resetDel()
  await fetchListData()
  ElMessage.success(message)
}

const resetDel = () => {
  delModel.value.ids = []
  loading.value = false
}

const delDialogClose = () => {
  if (loading.value) {
    return
  }
  resetDel()
  isShowDelDialog.value = false
}
/* 删除结束 */
</script>

<style scoped lang="scss">
.page-box {
  width: 100%;
  box-sizing: border-box;
  .search {
    padding: 20px 20px 0;
    background: #fff;
    margin-bottom: 10px;
    display: flex;
    flex-wrap: wrap;
    .el-form-item {
      margin: {
        right: 10px;
        bottom: 20px;
      }
    }
    .search-btn {
      margin-left: auto;
    }
    :deep(.el-input-number .el-input__inner) {
      text-align: left;
    }
    :deep(.el-range-editor.el-input__wrapper) {
      box-sizing: border-box;
    }
  }
  .head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 20px 20px 0;
    background: #fff;
    .title {
      font-size: 16px;
    }
  }
  .table {
    padding: 20px;
    background: #fff;
    .spec-item-box {
      width: 360px;
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      margin: {
        bottom: 6px;
      }
      .spec-item {
        margin: {
          right: 6px;
        }
      }
    }
  }
  .pagination {
    padding: 0 20px 20px;
    background: #fff;
    justify-content: flex-end;
    :last-child {
      margin-right: 0;
    }
  }
}
</style>